package com.hboxs.asl.pingpp.service.impl;

import com.hboxs.asl.pingpp.Config;
import com.hboxs.asl.pingpp.Constants;
import com.hboxs.asl.pingpp.service.PaymentService;
import com.pingplusplus.Pingpp;
import com.pingplusplus.exception.PingppException;
import com.pingplusplus.model.Charge;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * Service -- Ping++支付
 */
@Service(value = "pingppPaymentServiceImpl")
public class PaymentServiceImpl implements PaymentService {

    /**
     * 初始化
     */
    @PostConstruct
    public void init() {
        // 初始化配置
        Pingpp.apiKey = Config.API_KEY;
//        Pingpp.privateKeyPath =
        Pingpp.privateKey = Config.PRIVATE_KEY;
    }

    /**
     * 支付宝手机支付
     *
     * @param orderNo  商户订单号，适配每个渠道对此参数的要求，必须在商户系统内唯一。(alipay: 1-64 位， wx: 1-32 位，bfb: 1-20 位，upacp: 8-40 位，yeepay_wap:1-50 位，jdpay_wap:1-30 位，cnp_u:8-20 位，cnp_f:8-20 位，推荐使用 8-20 位，要求数字或字母，不允许特殊字符)。
     * @param channel  支付使用的第三方支付渠道
     * @param amount   订单总金额, 单位为对应币种的最小货币单位，例如：人民币为分（如订单总金额为 1 元，此处请填 100）。
     * @param clientIp 发起支付请求终端的 IP 地址，格式为 IPV4，如: 127.0.0.1。
     * @param subject  商品的标题，该参数最长为 32 个 Unicode 字符，银联全渠道（upacp/upacp_wap）限制在 32 个字节。
     * @param body     商品的描述信息，该参数最长为 128 个 Unicode 字符，yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。
     * @param extra    特定渠道发起交易时需要的额外参数以及部分渠道支付成功返回的额外参数。
     * @param description ORDER(订单)/CHARGE(充值)。
     * @return
     */
    @Override
    public Charge simpleCharge(String orderNo, String channel, String amount, String clientIp, String subject, String body, Map<String, String> extra, String description) throws PingppException {
        return standardCharge(orderNo, channel, amount, clientIp, subject, body, extra, null, null, description);
    }

    /**
     * 创建 Charge 对象
     *
     * @param orderNo     商户订单号，适配每个渠道对此参数的要求，必须在商户系统内唯一。(alipay: 1-64 位， wx: 1-32 位，bfb: 1-20 位，upacp: 8-40 位，yeepay_wap:1-50 位，jdpay_wap:1-30 位，cnp_u:8-20 位，cnp_f:8-20 位，推荐使用 8-20 位，要求数字或字母，不允许特殊字符)。
     * @param channel     支付使用的第三方支付渠道
     * @param amount      订单总金额, 单位为对应币种的最小货币单位，例如：人民币为分（如订单总金额为 1 元，此处请填 100）。
     * @param clientIp    发起支付请求终端的 IP 地址，格式为 IPV4，如: 127.0.0.1。
     * @param subject     商品的标题，该参数最长为 32 个 Unicode 字符，银联全渠道（upacp/upacp_wap）限制在 32 个字节。
     * @param body        商品的描述信息，该参数最长为 128 个 Unicode 字符，yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。
     * @param extra       (optional)特定渠道发起交易时需要的额外参数以及部分渠道支付成功返回的额外参数。
     * @param timeExpire  (optional)订单失效时间，用 Unix 时间戳表示。时间范围在订单创建后的 1 分钟到 15 天，默认为 1 天，创建时间以 Ping++ 服务器时间为准。 微信对该参数的有效值限制为 2 小时内；银联对该参数的有效值限制为 1 小时内。
     * @param metadata    (optional)参考 Metadata 元数据。
     * @param description (optional)订单附加说明，最多 255 个 Unicode 字符。
     * @return
     */
    @Override
    public Charge standardCharge(String orderNo, String channel, String amount, String clientIp, String subject, String body, Map<String, String> extra, String timeExpire, String metadata, String description) throws PingppException {
        return charge(orderNo, Config.APP_ID, channel, amount, clientIp, Constants.CURRENCY_CNY, subject, body, extra, timeExpire, metadata, description);
    }

    /**
     * 创建 Charge 对象
     *
     * @param orderNo     商户订单号，适配每个渠道对此参数的要求，必须在商户系统内唯一。(alipay: 1-64 位， wx: 1-32 位，bfb: 1-20 位，upacp: 8-40 位，yeepay_wap:1-50 位，jdpay_wap:1-30 位，cnp_u:8-20 位，cnp_f:8-20 位，推荐使用 8-20 位，要求数字或字母，不允许特殊字符)。
     * @param appId       支付使用的 app 对象的 id
     * @param channel     支付使用的第三方支付渠道
     * @param amount      订单总金额, 单位为对应币种的最小货币单位，例如：人民币为分（如订单总金额为 1 元，此处请填 100）。
     * @param clientIp    发起支付请求终端的 IP 地址，格式为 IPV4，如: 127.0.0.1。
     * @param currency    三位 ISO 货币代码，目前仅支持人民币 cny。
     * @param subject     商品的标题，该参数最长为 32 个 Unicode 字符，银联全渠道（upacp/upacp_wap）限制在 32 个字节。
     * @param body        商品的描述信息，该参数最长为 128 个 Unicode 字符，yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。
     * @param extra       (optional)特定渠道发起交易时需要的额外参数以及部分渠道支付成功返回的额外参数。
     * @param timeExpire  (optional)订单失效时间，用 Unix 时间戳表示。时间范围在订单创建后的 1 分钟到 15 天，默认为 1 天，创建时间以 Ping++ 服务器时间为准。 微信对该参数的有效值限制为 2 小时内；银联对该参数的有效值限制为 1 小时内。
     * @param metadata    (optional)参考 Metadata 元数据。
     * @param description (optional)订单附加说明，最多 255 个 Unicode 字符。
     * @return
     */
    private Charge charge(String orderNo, String appId, String channel, String amount, String clientIp, String currency, String subject, String body, Map<String, String> extra, String timeExpire, String metadata, String description) throws PingppException {
        Charge charge = null;
        Map<String, Object> chargeMap = new HashMap<>();
        chargeMap.put("order_no", orderNo);
        Map<String, String> app = new HashMap<>();
        app.put("id", appId);
        chargeMap.put("app", app);
        chargeMap.put("channel", channel);
        chargeMap.put("amount", amount);
        chargeMap.put("client_ip", clientIp);
        chargeMap.put("currency", currency);
        chargeMap.put("subject", subject);
        chargeMap.put("body", body);
        if (extra != null) {
            chargeMap.put("extra", extra);
        }
        if (!StringUtils.isEmpty(timeExpire)) {
            chargeMap.put("time_expire", timeExpire);
        }
        if (!StringUtils.isEmpty(metadata)) {
            chargeMap.put("metadata", metadata);
        }
        if (!StringUtils.isEmpty(description)) {
            chargeMap.put("description", description);
        }

        //发起交易请求
        charge = Charge.create(chargeMap);

        return charge;
    }
}
